%%%-------------------------------------------------------------------
%%% @doc  
%%% @end
%%%-------------------------------------------------------------------
-module(config_server).

-behaviour(gen_server).
%%--------------------------------------------------------------------
%% Include files
%%--------------------------------------------------------------------
-include("drproxy.hrl").

%%--------------------------------------------------------------------
%% API
%%--------------------------------------------------------------------
-export([
	 start_link/0, config/1, refresh/0, config_file/0, defaults/0
	 ]).

%%--------------------------------------------------------------------
%% gen_server callbacks
%%--------------------------------------------------------------------

-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
	terminate/2, code_change/3]).

%%--------------------------------------------------------------------
%% record definitions
%%--------------------------------------------------------------------

-record(state, {default, user}).

%%--------------------------------------------------------------------
%% macro definitions
%%--------------------------------------------------------------------

-define(SERVER, ?MODULE).

%%====================================================================
%% API
%%====================================================================
%%--------------------------------------------------------------------
%% @doc Starts the server.
%% @spec start_link() -> {ok, pid()} | {error, Reason}
%% @end
%%--------------------------------------------------------------------
start_link() ->
	gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

%%====================================================================
%% gen_server callbacks
%%====================================================================

%%--------------------------------------------------------------------
%% Function: init(Args) -> {ok, State} |
%%                         {ok, State, Timeout} |
%%                         ignore               |
%%                         {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
init([]) ->
	Default = defaults(),
	User = utils:config(config_file()),
	
	{ok, #state{default = Default, user = User}}.

config(Type) ->
	gen_server:call(?MODULE, {config, Type}).

refresh() ->
  gen_server:cast(?MODULE, refresh).

%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
%%                                      {reply, Reply, State, Timeout} |
%%                                      {noreply, State} |
%%                                      {noreply, State, Timeout} |
%%                                      {stop, Reason, Reply, State} |
%%                                      {stop, Reason, State}
%% Description: Handling call messages
%%--------------------------------------------------------------------
handle_call({config, Type}, _From, State) ->
  V = case catch dict:fetch(Type, State#state.user) of
		{'EXIT', _} ->
			case lists:keysearch(Type, 1, State#state.default) of
    		{value, {Type, Value}} ->
    			Value;
    		false ->
    			not_found
    	end;
		R ->
			R
	end,
	{reply, V, State};

handle_call(Msg, _From, State) ->
	error_logger:error_msg("Invalid call (config_server): ~w~n", [Msg]),
	{noreply, State}.

%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%%                                      {noreply, State, Timeout} |
%%                                      {stop, Reason, State}
%% Description: Handling cast messages
%%--------------------------------------------------------------------
handle_cast(refresh, State) ->
	User = utils:config(config_file()),
	{noreply, State#state{user = User}};

handle_cast(Msg, State) ->
	error_logger:error_msg("Invalid cast (config_server): ~w~n", [Msg]),
	{noreply, State}.

%%--------------------------------------------------------------------
%% Function: handle_info(Info, State) -> {noreply, State} |
%%                                       {noreply, State, Timeout} |
%%                                       {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info(Info, State) ->
	error_logger:error_msg("Invalid info (config_server): ~w~n", [Info]),
	{noreply, State}.

%%--------------------------------------------------------------------
%% Function: terminate(Reason, State) -> void()
%% Description: This function is called by a gen_server when it is about to
%% terminate. It should be the opposite of Module:init/1 and do any necessary
%% cleaning up. When it returns, the gen_server terminates with Reason.
%% The return value is ignored.
%%--------------------------------------------------------------------
terminate(_Reason, State) ->
	ok.

%%--------------------------------------------------------------------
%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
%% Description: Convert process state when code is changed
%%--------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) -> {ok, State}.
	
%%====================================================================
%%% Internal functions
%%====================================================================

defaults() ->
  [
  	{webport_server, 30383},
  	{server_concurrent_connections, 4096},
  	{servers, [node()]},
  	{server_first_port, 3010},
  	{request_timeout, 60000},
  	{debug, false},
  	{auth, false},
  	{frequency, 3.0}
	].

config_file() ->
	case application:get_env(drproxy, config) of
		{ok, Config} ->
			Config;
		_ ->
			error_logger:error_msg("The config file has not been specified~n"),
			exit({config, missing_config_file})
	end.